package top.jiangqiang.qyblog.core.storage.impl;

import lombok.extern.slf4j.Slf4j;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.http.SdkHttpResponse;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3Configuration;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
import software.amazon.awssdk.services.s3.model.DeleteObjectResponse;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import top.jiangqiang.qyblog.common.config.GlobalProperties;
import top.jiangqiang.qyblog.common.exception.JsonException;
import top.jiangqiang.qyblog.core.domain.StorageProperties;
import top.jiangqiang.qyblog.core.domain.entity.File;
import top.jiangqiang.qyblog.core.domain.entity.Storage;
import top.jiangqiang.qyblog.core.storage.AbstractS3StorageClient;

import java.io.InputStream;
import java.net.URI;
import java.util.function.Consumer;

@Slf4j
public class S3StorageClient extends AbstractS3StorageClient<S3Client> {

    public S3StorageClient(Storage storage, GlobalProperties globalProperties) {
        super(storage, globalProperties);
        this.client = buildS3Client(storage.getConfig());
    }

    @Override
    public boolean test() {
        try {
            this.client.listBuckets();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static boolean test(StorageProperties storageProperties) {
        try (S3Client s3Client = buildS3Client(storageProperties)) {
            try {
                s3Client.listBuckets();
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    }

    @Override
    public void upload(File file, InputStream inputStream, Consumer<File> completeCallback) {
        try {
            // 创建 PutObjectRequest 请求
            PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                    .bucket(properties.getBucket())
                    .key(file.getFileKey())
                    .build();
            RequestBody requestBody = RequestBody.fromInputStream(inputStream, file.getSize());
            // 执行上传请求
            PutObjectResponse response = client.putObject(putObjectRequest, requestBody);
            // 检查上传结果
            SdkHttpResponse sdkHttpResponse = response.sdkHttpResponse();
            if (sdkHttpResponse.isSuccessful()) {
                file.setState(1);
            } else {
                file.setState(3);
                completeCallback.accept(file);
            }
        } catch (Exception e) {
            log.debug("文件上传失败", e);
            throw new JsonException("文件上传失败", e);
        }
    }

    @Override
    public boolean delete(String fileKey) {
        DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder()
                .bucket(properties.getBucket())
                .key(fileKey)
                .build();
        DeleteObjectResponse response = client.deleteObject(deleteObjectRequest);
        SdkHttpResponse sdkHttpResponse = response.sdkHttpResponse();
        return sdkHttpResponse.isSuccessful();
    }


    /**
     * properties.setAccessKey("1AKIDtjNsY7i520xoefkosy1tZ7SRjwCVpBxm");
     * properties.setAccessSecret("2wsgXRLJIHHYqva9ZmkU6GDvPkvsaAanl");
     * properties.setBucket("test-1256657221");
     * properties.setEndpoint("cos.ap-shanghai.myqcloud.com");
     *
     * @param properties
     * @return
     */
    public static S3Client buildS3Client(StorageProperties properties) {
        return S3Client.builder()
                .region(Region.of(properties.getRegion()))
                .endpointOverride(URI.create(properties.getEndpointProtocol() + "://" + properties.getEndpoint()))
                .credentialsProvider(() -> AwsBasicCredentials.create(properties.getAccessKey(), properties.getAccessSecret()))
                .serviceConfiguration(S3Configuration.builder()
                        .chunkedEncodingEnabled(false)
                        .pathStyleAccessEnabled(properties.getEnablePathStyleAccess())
                        .build())
                .build();
    }

}
